import re
class Stack(object):
    # 初始化栈为空列表
    def __init__(self):
        self.items = []

    # 判断栈是否为空，返回布尔值
    def is_empty(self):
        return self.items == []

    # 返回栈顶元素
    def peek(self):
        return self.items[len(self.items) - 1]

    # 返回栈的大小
    def size(self):
        return len(self.items)

    # 把新的元素堆进栈里面（程序员喜欢把这个过程叫做压栈，入栈，进栈……）
    def push(self, item):
        self.items.append(item)

    # 把栈顶元素丢出去（程序员喜欢把这个过程叫做出栈……）
    def pop(self):
        return self.items.pop()
    def items(self):
        return self

# if __name__ == '__main__':
#     # 初始化一个栈对象
#     my_stack = Stack()
#     # 把'h'丢进栈里
#     my_stack.push('h')
#     # 把'a'丢进栈里
#     my_stack.push('a')
#     # 看一下栈的大小（有几个元素）
#     print(my_stack.size())
#     # 打印栈顶元素
#     print(my_stack.peek())
#     # 把栈顶元素丢出去，并打印出来
#     print(my_stack.pop())
#     # 再看一下栈顶元素是谁
#     print(my_stack.peek())
#     # 这个时候栈的大小是多少？
#     print(my_stack.size())
#     # 再丢一个栈顶元素
#     print(my_stack.pop())
#     # 看一下栈的大小
#     print(my_stack.size)
#     # 栈是不是空了？
#     print(my_stack.is_empty())
#     # 哇~真好吃~
#     print('Yummy~')
#定义运算符优先级
ops_level = {
    '+':1,
    '-':1,
    '*':2,
    '/':2,
}
#定义运算
def cal(n1, n2, op):
    n1 = float(n1)
    n2 = float(n2)
    if op == '+':
        print('+法',n1 + n2)
        return n1 + n2

    if op == '-':
        print('-法',n1 - n2)
        return n1 - n2

    if op == '*':
        print('乘法',n1,n2,n1 * n2)
        return n1 * n2

    if op == '/':
        print('除法',n1 / n2)
        return n1 / n2



sstring = '140/70*(4/5)*5/5-3*4/5+5/(3+5)+3/5*2/(1+3)'
print(sstring.strip())
#re匹配
xs = re.split('(\+|\-|\*|\/|\(|\))',sstring.strip())

#使用filter过滤器

x = [item for item in filter(lambda x: x!='',xs)]
print(x)

if __name__ == '__main__':


#临时存储运算符的栈S2（含一个结束符号），一个作为输入逆波兰式的栈S1（空栈）
#逻辑
# 1.如果是运算数直接压入S1 (else )
# 1.如果是运算符
#     1（直接压入
#     2.）(之间的运算符，逐个出栈，依次压入栈s2
#     3.如果不是（、）、则判断栈顶元素为（则直接压入，不是则判断。如果小于优先级，直接将其压入S2。直到优先级大于等于栈顶元素
# 2.遍历完以后检查S1是否为空，不为空则全部压入S2

    S1 = Stack()
    S2 = Stack()
    ss1 = S1.items
    ss2 = S2.items
    for i in range(0,len(x)):

        if x[i] == '(':
            S1.push(x[i])

        elif x[i] == ')':
            while S1.size() > 0:
                s1pop = S1.pop()
                if s1pop == '(':
                    break
                else:

                    S2.push(s1pop)




        elif x[i] in ['+','-','*','/']:
            print(x[i])
            if S1.size() > 0:

                if S1.peek() == '(' or ops_level[S1.peek()] < ops_level[x[i]]:
                    S1.push(x[i])
                    print('charu',x[i])
                    print(S1.items)


#运算符小于等于栈顶元素。出栈、并且，按照规矩入栈。
                else:
                    while S1.size()>0  and S1.peek() != '(':
                        if ops_level[S1.peek()] >= ops_level[x[i]] :
                            s1pop = S1.pop()
                            if s1pop == '(':
                                S1.push('(')
                                print('s12', S1.items, S2.items)
                                break

                            else:
                                print('s12',S1.items, S2.items)

                                S2.push(s1pop)

                                # if S1.size() == 1:
                                #     break

                    S1.push(x[i])


            else:

                S1.push(x[i])
        else:

            S2.push(x[i])
    if S1.size() == 0:
        print(S2.items)
    else:

        while S1.size() > 0:
            s1_pops = S1.pop()
            S2.push(s1_pops)
        print(S2.items)

#运算。
    reads = S2.items
    S3 = Stack()
    for i in reads:
        if i.isdigit() == True:
            S3.push(i)
            print('入栈数字',i)
        else:
            print(S3.items)
            if S3.size() > 1 :
                a = float(S3.pop())

                b = float(S3.pop())

                cal_result = cal(b,a,i)
                S3.push(cal_result)
                print('计算结果入栈数字', S3.peek())

